﻿namespace Pyramid.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Pyramid.IO;

    [TestClass]
    public class BinaryStreamFixture
    {
        [TestMethod]
        public void ShouldWriteAndReadATryte()
        {
            var memoryStream = new System.IO.MemoryStream();

            var target = new BinaryStream(memoryStream);

            target.WriteTryte(25);

            memoryStream.Position = 0;

            Assert.AreEqual(25, target.ReadTryte());
        }

        [TestMethod]
        public void ShouldWriteToAndReadFromAStream()
        {
            int tryteCount = 10;

            var memoryStream = new System.IO.MemoryStream();

            var target = new BinaryStream(memoryStream);

            var expected = GenerateTrytes(tryteCount).ToArray();

            target.Write(expected, 0, tryteCount);

            memoryStream.Position = 0;

            var actual = new Tryte[tryteCount];

            target.Read(actual, 0, tryteCount);

            Compare(expected, actual);
        }

        private static void Compare<T>(IEnumerable<T> expected, IEnumerable<T> actual)
        {
            if (expected.Count() != actual.Count())
            {
                Assert.Fail("Sets are not equal length.");
            }

            for (int itemIndex = 0; itemIndex < expected.Count(); itemIndex++)
            {
                Assert.AreEqual(expected.ElementAt(itemIndex), actual.ElementAt(itemIndex));
            }
        }

        private static readonly Random rnd = new Random();

        private static IEnumerable<Tryte> GenerateTrytes(int count)
        {
            for (int index = 0; index < count; index++)
            {
                yield return (Tryte)rnd.Next(Tryte.MaxValue);
            }
        }
    }
}
